﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace GameRobot
{
    public enum ControlType
    {
        ManualControl,
        ProgrammingControl,
        SchedulingControl
    }

    public class VirtualRobot
    {
        public RobotBridge _robotBridge;
        public string _robotName;
        public List<string> _listMethodUsed = new List<string>();
        public ControlType _controlType = ControlType.ManualControl;
        public int _IDTag;

        Thread _thread = null;
        bool[] _lock = new bool[]{false};
        object _locker = new object();
        List<MethodTag> _listMethod = new List<MethodTag>();

        public void SetMethods(List<MethodTag> listmethod)
        {
            if (_thread != null)
            {
                if (_thread.IsAlive)
                    return;
            }
            _listMethod = listmethod;
        }

        public bool IsActive()
        {
            if (_thread == null)
                return false;
            else
                return _thread.IsAlive;
        }

        public void SetMethod(MethodTag method)
        {
            _listMethod = new List<MethodTag>();
            _listMethod.Add(method);
        }

        public virtual void Start()
        {
            if (_thread != null)
            {
                if (_thread.IsAlive)
                    return;
            }
            _thread = new Thread(new ThreadStart(Action));
            _thread.Start();
        }

        public virtual void Stop()
        {
            GameMessage message = new GameMessage();
            message.message = messagedef.StopAllAction;

            lock (_locker)
            {
                _robotBridge.PushMessageB(message);
            }

            if (_thread != null)
                _thread.Abort();
            _thread = null;
        }

        public virtual void Pause()
        {
            //if (_thread != null)
            {
                _lock[0] = false;
                lock (_lock)
                {
                    while (!_lock[0])
                    {
                        Monitor.Wait(_lock);
                    }
                }
            }
            //_thread.Suspend();
        }

        public virtual void Resume()
        {
            //if (_thread != null)
            {
                lock (_lock)
                {
                    if (!_lock[0])
                    {
                        _lock[0] = true;
                        Monitor.Pulse(_lock);
                    }
                }
            }
            //_thread.Resume();
        }

        public void PushMessage(GameMessage message)
        {
            lock (_locker)
            {
                _robotBridge.PushMessageB(message);
            }

            GameMessage gm = PopMessage(true);
            while (gm != null)
            {
                ParseMessage(gm);
                gm = PopMessage(true);
            }

            Pause();

            gm = PopMessage(true);
            while (gm != null)
            {
                ParseMessage(gm);
                gm = PopMessage(true);
            }
        }

        public GameMessage PopMessage(bool isevent)
        {
            GameMessage message = null;
            lock (_locker)
            {
                if (isevent)
                    message = _robotBridge.PopMessageEvent();
                else
                    message = _robotBridge.PopMessageB();
            }
            return message;
        }

        public virtual void ParseMessage(GameMessage message)
        {
        }

        public void Action()
        {
            //_robotBridge._sender = this; // not problem
            _IDTag = 0;
            foreach (MethodTag t in _listMethod)
            {
                _robotBridge._sender = t._master as VirtualRobot;
                t.Execute();
                _IDTag++;
            }
        }
    }
}
